package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@DubboService
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate ;

    @Autowired
    private RedisIdService redisIdService;
    //保存动态
    @Override
    public void saveMovement(Movement movement) {
        //0.生成一个大数据需要使用到的主键
        Long pid = redisIdService.getNextId(ConstantUtil.MOVEMENT_ID);
        //1.保存用户发布的动态
        //完善默认数据

        movement.setPid(pid); //大数据id
        movement.setSeeType(1);//TODO 开发状态: 公开状态 谁都能看
        //movement.setState( 1 );//TODO 审核状态 0 表示未审核 1表示已审核  开发阶段默认写死
        movement.setCreated(System.currentTimeMillis()); //设置发布动态时间
        mongoTemplate.save(movement); //保存动态
        //2.往个人表中添加一个动态
        MyMovement myMovement = new MyMovement();
        //myMovement.setId(movement.getId()); //保存的就是大表中的主键
        myMovement.setPublishId(movement.getId());//保存的就是大表中的主键
        myMovement.setCreated( System.currentTimeMillis() );

        //参数2: collectionName 集合名称
        mongoTemplate.save(myMovement , ConstantUtil.MOVEMENT_MINE+ movement.getUserId());
        //3.查询好友关系
        Query query = new Query(
                Criteria.where("userId").is(  movement.getUserId() ) //拼接我的id
        );
        //查询看好友的关系
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //4.往好友的朋友圈中添加一条记录
        if(CollectionUtil.isNotEmpty(friendList)){
            //遍历每一个好友  往每一个好友的朋友圈中添加一条记录
            for (Friend friend : friendList) {
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId( movement.getId() );//发布的动态id
                friendMovement.setCreated(System.currentTimeMillis());//发布的时间
                friendMovement.setUserId( movement.getUserId()  );// 发布人动态id
                mongoTemplate.save(friendMovement , ConstantUtil.MOVEMENT_FRIEND + friend.getFriendId() );
            }
        }
    }

    //查看我的个人动态
    @Override
    public PageBeanVo findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1. 计算分页页码
        int startIndex = (pageNum -1) * pageSize;
        //2.查询我的动态
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created"))) //排序
                .skip(startIndex).limit(pageSize) //分页
                ;
        List<MyMovement> myMovements = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //3.根据查询我的动态 查询到我的动态详情数据\
        List<Movement> movementList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(myMovements)){
            for (MyMovement myMovement : myMovements) {
                ObjectId publishId = myMovement.getPublishId(); //我的动态id
                Movement movement = mongoTemplate.findById(publishId, Movement.class); //查询每一个我的动态详情
                if(movement.getState() ==1 ){//审核通过的动态才允许查询
                    movementList.add(movement);
                }
            }
        }
        //4.查询总记录数据
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        return new PageBeanVo(pageNum , pageSize , count ,movementList );
    }

    //查询好友的动态
    @Override
    public PageBeanVo findFriendMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.计算分页
        int startIndex = (pageNum - 1) * pageSize;
        //2.构建封装条件
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created"))) //排序
                .skip(startIndex).limit(pageSize) //分页
                ;
        //查询好友的动态
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        List<Movement> movementList = new ArrayList<>();
        //3.判断 并查询详细信息
        if(CollectionUtil.isNotEmpty(friendMovementList)){
            for (FriendMovement friendMovement : friendMovementList) {
                //查询动态详情
                ObjectId publishId = friendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                if(movement.getState()==1){//有效的朋友圈
                    movementList.add(movement);
                }
            }
        }

        long count = mongoTemplate.count(query, ConstantUtil.MOVEMENT_FRIEND + userId);
        return new PageBeanVo(pageNum , pageSize , count ,movementList );
    }

    //查询推荐的动态
    @Override
    public PageBeanVo findRecommendMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.计算分页
        int startIndex = (pageNum - 1) * pageSize;
        //2.查询推荐动态
        Query query = new Query(
                Criteria.where("userId").is(userId) //查询推荐给我的动态
        )
                .with(Sort.by(Sort.Order.desc("created"))) //排序
                .skip(startIndex).limit(pageSize) //分页
                ;
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        List<Movement> movementList = new ArrayList<>();
        //3.判断 遍历
        if(CollectionUtil.isNotEmpty(recommendMovementList)){
            for (RecommendMovement recommendMovement : recommendMovementList) {
                ObjectId id = recommendMovement.getPublishId();//动态id
                Movement movement = mongoTemplate.findById(id, Movement.class);//查询动态详情
                if(movement.getState() == 1){
                    movementList.add(movement);
                }
            }
        }
        long count = mongoTemplate.count(query, RecommendMovement.class);
        return new PageBeanVo(pageNum , pageSize ,count ,movementList );
    }

    //根据动态的id查询数据
    @Override
    public Movement findById(ObjectId publishId) {
        return mongoTemplate.findById( publishId , Movement.class);
    }


    // 后台查询动态数据
    @Override
    public PageBeanVo findMovementByPage(Long userId, Integer state, Integer pageNum, Integer pageSize) {
        //1.计算分页
        int startIndex = (pageNum - 1) * pageSize;
        //2,构建query
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(startIndex).limit(pageSize);

        if(userId!=null){ //如果用户id不为空 添加用户id
            query.addCriteria(Criteria.where("userId").is(userId));
        }
        if(state!=null){//如果状态不为空 添加状态
            query.addCriteria(Criteria.where("state").is(state));
        }
        //3.查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        Long counts = mongoTemplate.count(query, Movement.class);

        return new PageBeanVo(pageNum , pageSize ,counts ,  movementList);
    }

    //更新动态
    @Override
    public void updateMovement(Movement movement) {
        mongoTemplate.save(movement);//更新动态
    }
}
